﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Data;

namespace EasyBuildingCMS.BLL.CoreEngine
{
    public class BuildingBlockInstanceRepository : CoreEngineBaseRepository
    {
        public BuildingBlockInstanceRepository()
        {
            CacheKey += "_BuildingBlockInstance";
        }

        public BuildingBlockInstance GetBuildingBlockInstanceID(int buildingBlockInstanceID)
        {

            string key = string.Format(CacheKey + "_buildingBlockInstance_{0}", buildingBlockInstanceID);

            if (EnableCaching && (Cache[key] != null))
            {
                return (BuildingBlockInstance)Cache[key];
            }

            //this.CoreEngineContext.Pages.MergeOption = MergeOption.NoTracking;
            BuildingBlockInstance buildingBlockInstance = this.CoreEngineContext.BuildingBlockInstances.Where(p => p.BuildingBlockInstanceID == buildingBlockInstanceID).FirstOrDefault<BuildingBlockInstance>();

            if (EnableCaching)
            {
                CacheData(key, buildingBlockInstance, CacheDuration);
            }

            return buildingBlockInstance;
        }

        public List<Page> GetPublishedPages(bool PublishedOnly, int PageIndex, int PageSize)
        {
            string key = String.Format(
                CacheKey + "_{0}_{1}_{2}", PageIndex.ToString(), PageSize.ToString(), PublishedOnly.ToString());

            if (EnableCaching && Cache[key] != null)
            {
                return (List<Page>)Cache[key];
            }

            this.CoreEngineContext.Pages.MergeOption = MergeOption.NoTracking;
            List<Page> pages = null;

            if (PublishedOnly)
            {
                pages = (from page in CoreEngineContext.Pages
                         where page.Published
                         orderby page.PublishDate descending
                         select page).Skip(PageSize * PageIndex).Take(PageSize).ToList();
            }
            else
            {
                pages = (from page in CoreEngineContext.Pages
                         where page.Published
                         orderby page.PublishDate descending
                         select page).Skip(PageSize * PageIndex).Take(PageSize).ToList();
            }

            if (EnableCaching)
            {
                CacheData(key, pages, CacheDuration);
            }

            return pages;
        }

        public List<BuildingBlockInstance> GetSortedBuildingBlockInstanceByHolderPlace(int? pageID, string holderPlace)
        {

            string key = string.Format(CacheKey + "_sortedBuildingBlockInstanceByHolderPlace_{0}", holderPlace);

            if (EnableCaching && (Cache[key] != null))
            {
                return (List<BuildingBlockInstance>)Cache[key];
            }

            this.CoreEngineContext.Pages.MergeOption = MergeOption.NoTracking;
            List<BuildingBlockInstance> buildingBlockInstances = (from buildingBlockInstance in CoreEngineContext.BuildingBlockInstances
                                                                  where buildingBlockInstance.ContentPlaceHolderName == holderPlace && buildingBlockInstance.PageID == pageID
                                                                    orderby buildingBlockInstance.SortOrder 
                                                                    select buildingBlockInstance).ToList();
          
            if (EnableCaching)
            {
                CacheData(key, buildingBlockInstances, CacheDuration);
            }

            return buildingBlockInstances;
        }

        public List<string> GetContentHoldePlaceTypes(int pageID)
        {
            string key = CacheKey + "_contentHolderPlaceTypes"+pageID;

            if (EnableCaching && Cache[key] != null)
            {
                return (List<string>)Cache[key];
            }

            this.CoreEngineContext.MasterPage.MergeOption = MergeOption.NoTracking;

            List<string> contentHolderPlaceTypes = (from instance in CoreEngineContext.BuildingBlockInstances
                                                    where instance.Active && instance.PageID == pageID
                                                    select instance.ContentPlaceHolderName).Distinct<string>().ToList<string>();

            if (EnableCaching)
            {
                CacheData(key, contentHolderPlaceTypes, CacheDuration);
            }

            return contentHolderPlaceTypes;
        }

        public List<string> GetContentHoldePlaceTypes()
        {
            string key = CacheKey + "_contentHolderPlaceTypes";

            if (EnableCaching && Cache[key] != null)
            {
                return (List<string>)Cache[key];
            }

            this.CoreEngineContext.MasterPage.MergeOption = MergeOption.NoTracking;

            List<string> contentHolderPlaceTypes = (from instance in CoreEngineContext.BuildingBlockInstances
                                                    select instance.ContentPlaceHolderName).Distinct<string>().ToList<string>();

            if (EnableCaching)
            {
                CacheData(key, contentHolderPlaceTypes, CacheDuration);
            }

            return contentHolderPlaceTypes;
        }

        public bool UpdateSortOrder(int buildingBlockInstanceID, int order)
        {
            BuildingBlockInstance buildingBlockInstance = this.GetBuildingBlockInstanceID(buildingBlockInstanceID);
            buildingBlockInstance.SortOrder = order;

            return base.SaveChange(buildingBlockInstanceID);
        }

        #region Insert

        public BuildingBlockInstance InsertBuildingBlockInstance(int buildingBlockInstanceID, int? pageID, string friendName, int buildingBlockID, string description, string placeHolderName)
        {
            BuildingBlockInstance buildingBlockInstance = BuildingBlockInstance.CreateBuildingBlockInstance(buildingBlockInstanceID, buildingBlockID, true);
            buildingBlockInstance.PageID = pageID;
            buildingBlockInstance.BuildingBlockInstanceFriendlyName = friendName;
            buildingBlockInstance.BuildingBlockInstanceDescription = description;
            buildingBlockInstance.ContentPlaceHolderName = placeHolderName;

            return this.InsertBuildingBlockInstance(buildingBlockInstance);

        }

        public BuildingBlockInstance InsertBuildingBlockInstance(BuildingBlockInstance buildingBlockInstance)
        {

            try
            {
                if (buildingBlockInstance.EntityState == EntityState.Detached)
                {
                    this.CoreEngineContext.AddToBuildingBlockInstances(buildingBlockInstance);
                }
                if (base.SaveChange(buildingBlockInstance.BuildingBlockInstanceID))
                {
                    return buildingBlockInstance;
                }
                else
                {
                    return null;
                }
            }
            catch (Exception ex)
            {
                ActiveExceptions.Add(CacheKey + "_" + buildingBlockInstance.PageID, ex);
                return null;

            }
        }

        #endregion

        #region " Delete Operations "

        public bool DeleteBuildingBlockInstance(int buildingBlockInstanceID)
        {
            return ChangeDeletedState(this.GetBuildingBlockInstanceID(buildingBlockInstanceID), false);
        }

        public bool DeletePage(BuildingBlockInstance buildingBlockInstance)
        {
            return ChangeDeletedState(buildingBlockInstance, false);
        }

        public bool UnDeletePage(BuildingBlockInstance buildingBlockInstance)
        {
            return ChangeDeletedState(buildingBlockInstance, true);
        }

        private bool ChangeDeletedState(BuildingBlockInstance buildingBlockInstance, bool state)
        {
            buildingBlockInstance.Active = state;
            return base.SaveChange(buildingBlockInstance.BuildingBlockInstanceID);
        }

        #endregion

    }
   
}
